package tr.richfacesext.components.captcha;

import java.awt.image.BufferedImage;
import java.io.IOException;

import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.context.ResponseWriter;
import javax.faces.render.Renderer;

import tr.richfacesext.components.captcha.core.CaptchaImage;
import tr.richfacesext.components.captcha.core.CaptchaImageImpl;
import tr.richfacesext.components.imgviewer.ImgViewerConstants;

/**
 * 
 * @author mert
 *
 */
public class CaptchaRenderer extends Renderer {
	
	public void encodeEnd(FacesContext context, UIComponent component) throws IOException {
		ResponseWriter writer = context.getResponseWriter();
		Captcha captcha = (Captcha) component;
		BufferedImage bufferedImage = generateCaptchaImage(context, captcha);
		
		writer.startElement("span", captcha);
		writer.startElement("img", captcha);
		writer.writeAttribute("id", "captcha_" + captcha.getId(), null);
		
		String contextPath = context.getExternalContext().getRequestContextPath();
		writer.writeAttribute("src", contextPath + "/" + ImgViewerConstants.IMAGEVIEWER_VIEW_ID + "?" + 
									 ImgViewerConstants.KEYVAL_IMAGEID + "=" + "key_" + captcha.getId(), null);
		
		writer.endElement("img");
		writer.endElement("span");
		
		putImgToSession(context, captcha, bufferedImage);
	}
	
	private BufferedImage generateCaptchaImage(FacesContext context, Captcha captcha) {
		String captchaKey = generateCaptchaKey(captcha);
		putCaptchaKeyToSession(context, captcha.getId(), captchaKey);
		
		CaptchaImage imageCreator = new CaptchaImageImpl(captcha.getLetterWidth(), captcha.getMaxLength(), captcha.getImgHeight(), captcha.getDrawLines(), captcha.getDrawBoxes(), captcha.getImgSkew(), captcha.getInvertColors());
		return imageCreator.skewImage(captchaKey);
	}

	private void putCaptchaKeyToSession(FacesContext context, String id, String captchaKey) {
		context.getExternalContext().getSessionMap().put(id, captchaKey);
	}

	private String generateCaptchaKey(Captcha captcha) {
	    String key = new String("");
	    for (int i = 0; i < captcha.getMaxLength(); i++) {
	        key += (char) (65 + (Math.random() * 24));
	    }
	    key = key.replaceAll("I","X");
	    key = key.replaceAll("Q","Z");
	    
	    return key;
	}	
	
	private void putImgToSession(FacesContext context, Captcha captcha, BufferedImage bufferedImage) {
		context.getExternalContext().getSessionMap().put("key_" + captcha.getId(), bufferedImage);
	}
}